package hust.rpc.proxy;

import hust.rpc.exception.MethodInvokeException;
import hust.rpc.utils.SignatureUtils;
import javafx.util.Pair;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class ProviderProxy extends Proxy {

    private final Map<String, Pair<Method, Object>> cache = new HashMap<>();

    @Override
    protected <T> T getInternalProxy(Class<T> clazz) {
        try {
            T t = clazz.newInstance();
            for (Class<?> service : clazz.getInterfaces()) {
                for (Method method : service.getDeclaredMethods()) {
                    cache.put(SignatureUtils.getSignature(method), new Pair<>(method, t));
                }
            }
            return t;
        } catch (InstantiationException | IllegalAccessException e) {
            throw new MethodInvokeException("创建服务实现类失败: " + e);
        }
    }

    @Override
    public Object invoke(String signature, Object[] args) throws InvocationTargetException, IllegalAccessException {
        Pair<Method, Object> cacheInfo = cache.get(signature);
        if (cacheInfo == null) {
            throw new RuntimeException("没有找到调用方法信息!");
        }
        return cacheInfo.getKey().invoke(cacheInfo.getValue(), args);
    }
}
